package com.itsu.app.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.itsu.app.exception.MyException;
import com.itsu.app.interceptor.UserThreadLocal;
import com.itsu.interfaces.entity.*;
import com.itsu.interfaces.service.*;
import com.itsu.pojo.enums.ResultCode;
import com.itsu.pojo.results.ErrorResult;
import com.itsu.pojo.vo.DimensionVo;
import com.itsu.pojo.vo.ReportVo;
import com.itsu.pojo.vo.SimilarYouVo;
import com.itsu.pojo.vo.TestSoulOptionVo;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class AppTestSoulService {

    @Reference
    TestSoulQuestionnaireService questionnaireService;

    @Reference
    TestSoulQuestionsService questionsService;

    @Reference
    TestSoulOptionService optionService;

    @Reference
    ScoreService scoreService;

    @Reference
    UserResultService userResultService;

    @Reference
    TestResultService testResultService;

    @Autowired
    AppUserInfoService appUserInfoService;


    public List<TestSoulQuestionnaire> getQuestionnaire() {
        List<TestSoulQuestionnaire> questionnaireList = questionnaireService.getAll();
        if (CollUtil.isEmpty(questionnaireList)) {
            throw new MyException(new ErrorResult(ResultCode.USER_REGIT_ERROR));
        }

        List<TestSoulQuestion> questionList = questionsService.getAll();
        if (CollUtil.isEmpty(questionList)) {
            throw new MyException(new ErrorResult(ResultCode.USER_REGIT_ERROR));
        }

        for (TestSoulQuestion testSoulQuestion : questionList) {
            List<TestSoulOptionVo> voList = new ArrayList<>();
            List<TestSoulOption> soulOptions = optionService.findByQid(testSoulQuestion.getId());
            for (TestSoulOption soulOption : soulOptions) {
                TestSoulOptionVo vo = new TestSoulOptionVo();
                vo.setId(Convert.toInt(soulOption.getId()));
                vo.setOption(soulOption.getName());
                voList.add(vo);
                testSoulQuestion.setOptions(voList);
            }
        }


        for (TestSoulQuestionnaire testSoulQuestionnaire : questionnaireList) {
            testSoulQuestionnaire.setQuestions(questionList);
        }

        return questionnaireList;
    }

    public Map<String, Long> submitQuestionnaire(Integer queationId, Integer optionId) {
        Map<String, Long> date = new HashMap<>();

        Score score = scoreService.findByQidAndOid(Convert.toLong(queationId), Convert.toLong(optionId));

        UserResult userResult = userResultService.findByUid(UserThreadLocal.getUid());

        Long resultId = null;
        if (ObjectUtil.isEmpty(userResult)) {
            userResult = new UserResult();
            resultId = getResultId(score.getScore());
            userResult.setResultId(resultId);
            userResult.setUserId(UserThreadLocal.getUid());
            userResult.setScore(score.getScore());
            userResultService.save(userResult);
            date.put("id", resultId);
            return date;
        }

        resultId = getResultId(score.getScore() + userResult.getScore());
        userResult.setResultId(resultId);
        userResult.setUserId(UserThreadLocal.getUid());
        userResult.setScore(score.getScore() + userResult.getScore());
        userResultService.updateByUid(userResult);
        date.put("id", resultId);
        return  date;
    }


    private Long getResultId(Long score) {
        if (score > 0 && score <= 20) {
            return 1L;
        }

        if (score >= 21 && score <= 40) {
            return 2L;
        }

        if (score >= 41 && score <= 55) {
            return  3L;
        }
        return 5L;
    }

    public ReportVo getReport(Long id) {
        TestResult result = testResultService.findByRid(id);
        if (ObjectUtil.isEmpty(result)) {
            throw new MyException(new ErrorResult(ResultCode.USER_REGIT_ERROR));
        }
        List<UserResult> userResults = userResultService.findListByRid(id, UserThreadLocal.getUid());
        if (ObjectUtil.isEmpty(userResults)) {
            throw new MyException(new ErrorResult(ResultCode.USER_REGIT_ERROR));
        }

        ReportVo reportVo = new ReportVo();
        reportVo.setConclusion(result.getConclusion());
        reportVo.setCover(result.getCover());

        List<DimensionVo> dimensions = new ArrayList<>();
        dimensions.add(getVoByType(result.getOutValue()));
        dimensions.add(getVoByType(result.getReasonValue()));
        dimensions.add(getVoByType(result.getAbstractValue()));
        dimensions.add(getVoByType(result.getJudgmentValue()));
        reportVo.setDimensions(dimensions);

        List<Long> userIds = CollUtil.getFieldValues(userResults, "userId", Long.class);
        List<UserInfoEntity> userByUids = appUserInfoService.findUserByUids(userIds);
        List<SimilarYouVo> similarYou = new ArrayList<>();
        for (UserInfoEntity entity : userByUids) {
            SimilarYouVo sVo = new SimilarYouVo();
            sVo.setId(Convert.toInt(entity.getUserId()));
            sVo.setAvatar(entity.getLogo());
            similarYou.add(sVo);
        }
        reportVo.setSimilarYou(similarYou);

        return reportVo;
    }


    private DimensionVo getVoByType(String code) {
        DimensionVo dimensionVo = new DimensionVo();
        String[] split = code.split("-");
        if ("o".equals(split[0])) {
            dimensionVo.setKey("外向");
        }
        if ("a".equals(split[0])) {
            dimensionVo.setKey("抽象");
        }
        if ("r".equals(split[0])) {
            dimensionVo.setKey("理性");
        }
        if ("j".equals(split[0])) {
            dimensionVo.setKey("判断");
        }
        dimensionVo.setValue(split[1] + "%");
        return dimensionVo;
    }
}



